
// <copyright file="DynamicDAO.Select.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The dynamic dao.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data.Dynamic
{
    using System.Collections.Generic;
    using System.Data;

    /// <summary>
    /// The dynamic dao.
    /// </summary>
    /// <typeparam name="E">
    /// </typeparam>
    public static partial class DynamicDAO<E>
    {
        #region Public Methods and Operators

        /// <summary>
        /// The select.
        /// </summary>
        /// <param name="whereClause">
        /// The where clause.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="whereClauseConditions">
        /// The where clause conditions.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> Select(string whereClause, string tableName = null, params ClauseCondition[] whereClauseConditions)
        {
            IDbConnection connection = getConnection();
            return select(whereClause, connection, null, true, tableName, whereClauseConditions);
        }

        /// <summary>
        /// The select.
        /// </summary>
        /// <param name="whereClause">
        /// The where clause.
        /// </param>
        /// <param name="connection">
        /// The connection.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="whereClauseConditions">
        /// The where clause conditions.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> Select(string whereClause, IDbConnection connection, string tableName = null, params ClauseCondition[] whereClauseConditions)
        {
            return select(whereClause, connection, null, false, tableName, whereClauseConditions);
        }

        /// <summary>
        /// The select.
        /// </summary>
        /// <param name="whereClause">
        /// The where clause.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="whereClauseConditions">
        /// The where clause conditions.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> Select(string whereClause, IDbTransaction transaction, string tableName = null, params ClauseCondition[] whereClauseConditions)
        {
            return select(whereClause, null, transaction, false, tableName, whereClauseConditions);
        }

        /// <summary>
        /// The select all.
        /// </summary>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> SelectAll(string tableName = null)
        {
            IDbConnection connection = getConnection();
            return select(null, connection, null, true, tableName, null);
        }

        /// <summary>
        /// The select all.
        /// </summary>
        /// <param name="connection">
        /// The connection.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> SelectAll(IDbConnection connection, string tableName = null)
        {
            return Select(null, connection, tableName);
        }

        /// <summary>
        /// The select all.
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<E> SelectAll(IDbTransaction transaction, string tableName = null)
        {
            return Select(null, transaction, tableName);
        }

        /// <summary>
        /// The select one.
        /// </summary>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="keys">
        /// The keys.
        /// </param>
        /// <returns>
        /// The <see cref="E"/>.
        /// </returns>
        public static E SelectOne(string tableName = null, params object[] keys)
        {
            IDbConnection connection = getConnection();
            using (connection)
            {
                return SelectOne(connection, tableName, keys);
            }
        }

        /// <summary>
        /// The select one.
        /// </summary>
        /// <param name="connection">
        /// The connection.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="keys">
        /// The keys.
        /// </param>
        /// <returns>
        /// The <see cref="E"/>.
        /// </returns>
        public static E SelectOne(IDbConnection connection, string tableName = null, params object[] keys)
        {
            IDbCommand command = connection.CreateCommand();
            initializeCommandForSelectOne(command, tableName, keys);
            IDataReader reader = command.ExecuteReader();
            if (reader.Read())
            {
                return createEntityFromRecord(reader);
            }

            return null;
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// The select.
        /// </summary>
        /// <param name="whereClause">
        /// The where clause.
        /// </param>
        /// <param name="connection">
        /// The connection.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <param name="closeConnectionAfterReading">
        /// The close connection after reading.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="whereClauseConditions">
        /// The where clause conditions.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        private static IEnumerable<E> select(string whereClause, IDbConnection connection, IDbTransaction transaction, bool closeConnectionAfterReading, string tableName, params ClauseCondition[] whereClauseConditions)
        {
            IDbCommand command;
            if (transaction != null)
            {
                command = transaction.Connection.CreateCommand();
                command.Transaction = transaction;
            }
            else
            {
                command = connection.CreateCommand();
            }

            command.CommandText = tableName == null ? _selectCommand : string.Format(_selectCommandFormat, tableName);
            initializeCommandWithWhereClause(command, whereClause, whereClauseConditions);
            IDataReader reader = command.ExecuteReader();
            return new DataReaderEnumerable<E>(reader, createEntityFromRecord, command.Connection, closeConnectionAfterReading);
        }

        #endregion Methods
    }
}